<html>
<head><meta charset="utf-8"><title>size_of never type? · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html">size_of never type?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="245624420"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245624420" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245624420">(Jul 11 2021 at 20:14)</a>:</h4>
<p>Is it weird that <code>size_of::&lt;!&gt;()</code> is 0? It just occurs to me that size_of normally can't be called on types that aren't Sized, and I think(?) that <code>!</code> isn't Sized, and yet as the bottom type I'm not sure if it makes sense to exclude it from anything? I can't think of any concrete risk, I'm just being wary.</p>



<a name="245624566"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245624566" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245624566">(Jul 11 2021 at 20:18)</a>:</h4>
<p><code>!: Sized</code> is satisfied.</p>



<a name="245624581"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245624581" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245624581">(Jul 11 2021 at 20:19)</a>:</h4>
<p>An empty type can even have a non-zero size I think. Eg <code>struct Foo([u8; 16], !)</code> is 16 bytes I think.</p>



<a name="245624859"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245624859" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245624859">(Jul 11 2021 at 20:26)</a>:</h4>
<p>Ah, good point. Is <code>!: Sized</code> because it actually implements Sized, or is it because as the bottom type it implicitly satisfies everything? I don't see the usual blanket impls that I would expect on Sized types, e.g. the docs don't show the <code>impl&lt;T: ?Sized&gt; Borrow&lt;T&gt; for T</code>. But I guess I also don't understand why <code>!</code> has to have explicit implementations for <code>Clone</code>, <code>Display</code>, etc</p>



<a name="245625441"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625441" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625441">(Jul 11 2021 at 20:40)</a>:</h4>
<p>Sized is an auto trait, so <code>!</code> doesn't need to explicitly implement it.</p>



<a name="245625448"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625448" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625448">(Jul 11 2021 at 20:41)</a>:</h4>
<p>There were proposals to make size_of::&lt;!&gt; a negative infinity, represented in whatever way, at some point.</p>



<a name="245625504"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625504" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625504">(Jul 11 2021 at 20:42)</a>:</h4>
<p>that'd be a good april fools day RFC, change size_of to return a float :)</p>



<a name="245625569"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625569" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625569">(Jul 11 2021 at 20:44)</a>:</h4>
<p>the thing is, whether ! is Sized or not doesn't really matter all that much</p>



<a name="245625595"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625595" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625595">(Jul 11 2021 at 20:45)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/213817-t-lang/topic/size_of.20never.20type.3F/near/245625441">said</a>:</p>
<blockquote>
<p>Sized is an auto trait, so <code>!</code> doesn't need to explicitly implement it.</p>
</blockquote>
<p>I think it's something even more magical than an auto trait, Unpin is defined as <code>pub auto trait Unpin</code> but Sized is just <code>pub trait Sized</code></p>



<a name="245625619"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625619" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lukas Wirth <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625619">(Jul 11 2021 at 20:45)</a>:</h4>
<p><span class="user-mention silent" data-user-id="123586">nagisa</span> <a href="#narrow/stream/213817-t-lang/topic/size_of.20never.20type.3F/near/245625569">said</a>:</p>
<blockquote>
<p>the thing is, whether ! is Sized or not doesn't really matter all that much</p>
</blockquote>
<p>Wouldn't it matter for things like <code>Result&lt;u32, !&gt;</code>? If it wasn't sized the enum here wouldn't be sized either which means you couldn't pass it by value right?</p>



<a name="245625670"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625670" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625670">(Jul 11 2021 at 20:46)</a>:</h4>
<p><code>!</code> works on a different layer than sizes: an uninhabited type can have a size but all bit patterns of that size are invalid for that type.</p>



<a name="245625677"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625677" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625677">(Jul 11 2021 at 20:46)</a>:</h4>
<p>On one hand yeah, on the other you could argue that since the variants with <code>!</code> aren't constructible, they shouldn't be considered for the purposes of determining the containers' sizedness.</p>



<a name="245625692"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625692" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625692">(Jul 11 2021 at 20:47)</a>:</h4>
<p><span class="user-mention" data-user-id="300586">@Lukas Wirth</span> Enums with unsized fields aren't even allowed at all.</p>



<a name="245625693"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625693" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625693">(Jul 11 2021 at 20:47)</a>:</h4>
<p>but all things considered <code>!: Sized</code> makes things overall significantly less hacky, probably?</p>



<a name="245625742"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625742" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625742">(Jul 11 2021 at 20:48)</a>:</h4>
<p><code>!</code>  should be as unsurprising as possible: it should be identical to <code>()</code> in every way except that it has no valid values instead of just one.</p>



<a name="245625751"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245625751" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245625751">(Jul 11 2021 at 20:48)</a>:</h4>
<p>So <code>!</code> would be <code>Sized</code> and <code>Copy</code>, and it wouldn't matter since you'd never get around to creating a value to copy.</p>



<a name="245629847"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245629847" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245629847">(Jul 11 2021 at 22:12)</a>:</h4>
<p><code>MaybeUninit&lt;!&gt;</code> exists and has size 0 (It can store a single value, <code>MaybeUninit::uninit()</code>, though you could argue that <code>MaybeUnini::zeroed()</code> is distinct). Because <code>MaybeUninit&lt;T&gt;</code> has the same size and alignment as <code>T</code>, then <code>!</code> must also have size 0.</p>



<a name="245646157"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245646157" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245646157">(Jul 12 2021 at 05:15)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/213817-t-lang/topic/size_of.20never.20type.3F/near/245624581">said</a>:</p>
<blockquote>
<p>An empty type can even have a non-zero size I think. Eg <code>struct Foo([u8; 16], !)</code> is 16 bytes I think.</p>
</blockquote>
<p>See also <a href="https://github.com/rust-lang/rust/issues/54987">https://github.com/rust-lang/rust/issues/54987</a> for why it really needs to be nonzero size. The <code>!</code> type really needs to be a regular ZST, not a magic negative infinity size type that ZSTs anything it is tupled with, because of partial initialization. It's not a slam dunk argument because this is not allowed today and I don't know whether it will become safe in the future:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">x</span>: <span class="p">([</span><span class="kt">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">16</span><span class="p">],</span><span class="w"> </span><span class="o">!</span><span class="p">);</span><span class="w"></span>
<span class="n">x</span><span class="p">.</span><span class="mi">0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="k">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">16</span><span class="p">];</span><span class="w"></span>
<span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="mi">0</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>But especially for generic code, one really would like this to work:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#![feature(never_type)]</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="cp">#[repr(C)]</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">([</span><span class="kt">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">16</span><span class="p">],</span><span class="w"> </span><span class="n">T</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">MaybeUninit</span>::<span class="o">&lt;</span><span class="n">Foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span>::<span class="n">uninit</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">field</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">std</span>::<span class="n">ptr</span>::<span class="n">addr_of_mut</span><span class="o">!</span><span class="p">((</span><span class="o">*</span><span class="n">x</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">()).</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">field</span><span class="p">.</span><span class="n">write</span><span class="p">([</span><span class="mi">0</span><span class="k">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">16</span><span class="p">])</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">field</span><span class="p">.</span><span class="n">read</span><span class="p">()</span><span class="w"> </span><span class="p">});</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">foo</span>::<span class="o">&lt;!&gt;</span><span class="p">()</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="245720271"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/size_of%20never%20type%3F/near/245720271" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jeremiah Senkpiel <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/size_of.20never.20type.3F.html#245720271">(Jul 12 2021 at 17:37)</a>:</h4>
<p>It seems reasonable enough to me (a bystander) that something which can't be represented in actuality has a size of 0.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>